/**
 * @author: tangjianan
 * @date: 2025-06-25
 * @description: CesiumMap.js
 * @version: 1.0.0
 * @copyright: 2025 tangjianan
 * @license: MIT
 * @contact: tjn246@126.com
 * @description: CesiumMap.js 详细见README.md和下方注释
 */

// CesiumMap.js
// 通用 Cesium 地图封装
import * as Cesium from 'cesium';

// 设置 Cesium ion 访问令牌（token）
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxZWJhYTFjOS0wMTFmLTQ4ZTQtODMwNi02ZTUzZDEwNjAwNzUiLCJpZCI6MjQwMTgxLCJpYXQiOjE3NTA3NTQwMDl9.IcJQj9vCf6BzBOX9ymWzmnQXIB9rLbJ-ycS88CrRTq0';

/**
 * CesiumMap 封装类，统一管理 Cesium 地图常用操作
 */
export default class CesiumMap {
  /**
   * 构造函数，初始化 Cesium Viewer
   * @param {string|HTMLElement} containerId - 容器 DOM 或 id
   * @param {object} options - Cesium.Viewer 支持的初始化参数
   */
  constructor(containerId, options = {}) {
    this.viewer = new Cesium.Viewer(containerId, {
      animation: false,
      timeline: false,
      baseLayerPicker: false,
      geocoder: false,
      homeButton: false,
      sceneModePicker: false,
      navigationHelpButton: false,
      infoBox: false,
      ...options
    });
  }

  /**
   * 添加实体（点、线、面、billboard等）
   * @param {object} entityOptions - Cesium.Entity 支持的参数
   * @returns {Entity} - 返回添加的实体对象
   */
  addEntity(entityOptions) {
    return this.viewer.entities.add(entityOptions);
  }

  /**
   * 移除实体
   * @param {Entity} entity - 需要移除的实体对象
   */
  removeEntity(entity) {
    this.viewer.entities.remove(entity);
  }

  /**
   * 相机飞行到目标实体或位置
   * @param {Entity|object|Cartesian3|Array} target - 目标实体、位置或经纬度数组
   * @param {object} options - 飞行参数
   * @returns {Promise}
   */
  flyTo(target, options = {}) {
    if (typeof Cesium !== 'undefined' && Cesium.Entity && target instanceof Cesium.Entity) {
      return this.viewer.flyTo(target, options);
    } else if (typeof Cesium !== 'undefined' && Cesium.Cartesian3 && target instanceof Cesium.Cartesian3) {
      return this.viewer.camera.flyTo({
        destination: target,
        ...options
      });
    } else if (Array.isArray(target) && (target.length === 2 || target.length === 3)) {
      // 支持直接传 [lon, lat] 或 [lon, lat, height]
      const [lon, lat, height = 1000] = target;
      const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
      return this.viewer.camera.flyTo({
        destination: position,
        ...options
      });
    } else {
      return this.viewer.flyTo(target, options);
    }
  }

  /**
   * 添加影像图层
   * @param {ImageryProvider} provider - 影像图层提供者
   * @returns {ImageryLayer}
   */
  addImageryProvider(provider) {
    return this.viewer.imageryLayers.addImageryProvider(provider);
  }

  /**
   * 移除影像图层
   * @param {ImageryLayer} layer - 影像图层对象
   */
  removeImageryLayer(layer) {
    this.viewer.imageryLayers.remove(layer);
  }

  /**
   * 添加图标标记（billboard marker）
   * @param {object} param0 - { lon, lat, height, image, width, heightPx, name, description }
   * @returns {Entity}
   */
  addMarker({ lon, lat, height = 0, image, width = 32, heightPx = 32, name = '', description = '' }) {
    return this.viewer.entities.add({
      name,
      position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
      billboard: {
        image,
        width,
        height: heightPx,
      },
      description,
    });
  }

  /**
   * 添加折线（polyline）
   * @param {object} param0 - { positions, color, width, name, description }
   * @returns {Entity}
   */
  addPolyline({ positions, color = Cesium.Color.BLUE, width = 3, name = '', description = '' }) {
    return this.viewer.entities.add({
      name,
      polyline: {
        positions: positions.map(p => Cesium.Cartesian3.fromDegrees(...p)),
        width,
        material: color,
      },
      description,
    });
  }

  /**
   * 添加圆（ellipse）
   * @param {object} param0 - { lon, lat, radius, color, outlineColor, outlineWidth, name, description }
   * @returns {Entity}
   */
  addCircle({ lon, lat, radius, color = Cesium.Color.GREEN.withAlpha(0.5), outlineColor = Cesium.Color.GREEN, outlineWidth = 2, name = '', description = '' }) {
    return this.viewer.entities.add({
      name,
      position: Cesium.Cartesian3.fromDegrees(lon, lat),
      ellipse: {
        semiMajorAxis: radius,
        semiMinorAxis: radius,
        material: color,
        outline: true,
        outlineColor,
        outlineWidth,
      },
      description,
    });
  }

  /**
   * 添加多边形
   * @param {object} param0 - { positions, color, outlineColor, outlineWidth, name, description }
   * @returns {Entity}
   */
  addPolygon({ positions, color = Cesium.Color.YELLOW.withAlpha(0.5), outlineColor = Cesium.Color.YELLOW, outlineWidth = 2, name = '', description = '' }) {
    return this.viewer.entities.add({
      name,
      polygon: {
        hierarchy: positions.map(p => Cesium.Cartesian3.fromDegrees(...p)),
        material: color,
        outline: true,
        outlineColor,
        outlineWidth,
      },
      description,
    });
  }

  /**
   * 添加围栏（拉伸多边形）
   * @param {object} param0 - { positions, height, color, outlineColor, outlineWidth, name, description }
   * @returns {Entity}
   */
  addFence({ positions, height = 100, color = Cesium.Color.CYAN.withAlpha(0.5), outlineColor = Cesium.Color.CYAN, outlineWidth = 2, name = '', description = '' }) {
    return this.viewer.entities.add({
      name,
      polygon: {
        hierarchy: positions.map(p => Cesium.Cartesian3.fromDegrees(...p)),
        extrudedHeight: height,
        material: color,
        outline: true,
        outlineColor,
        outlineWidth,
      },
      description,
    });
  }

  /**
   * 添加弧形（polyline）
   * @param {object} param0 - { center, radius, startAngle, endAngle, color, width, count, name, description }
   * @returns {Entity}
   */
  addArc({ center, radius, startAngle, endAngle, color = CesiumMap.Color.PURPLE, width = 3, count = 64, name = '', description = '' }) {
    const positions = CesiumMap.generateArcPoints(center, radius, startAngle, endAngle, count)
      .map(p => CesiumMap.Cartesian3.fromDegrees(...p));
    return this.viewer.entities.add({
      name,
      polyline: {
        positions,
        width,
        material: color,
      },
      description,
    });
  }

  /**
   * 注册鼠标事件
   * @param {ScreenSpaceEventType} type - 事件类型（如 LEFT_CLICK）
   * @param {function} callback - 回调函数
   */
  addScreenSpaceEventHandler(type, callback) {
    if (!this.handler) {
      this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    }
    this.handler.setInputAction(callback, type);
  }

  /**
   * 移除鼠标事件
   * @param {ScreenSpaceEventType} type - 事件类型
   */
  removeScreenSpaceEventHandler(type) {
    if (this.handler) {
      this.handler.removeInputAction(type);
    }
  }

  /**
   * 注册实体点击事件回调
   * @param {function} callback - 回调函数，参数为entity和点击位置{entity, position, screenPosition}
   */
  onEntityClick(callback) {
    if (!this._entityClickHandler) {
      this._entityClickHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    }
    this._entityClickHandler.setInputAction((movement) => {
      const picked = this.viewer.scene.pick(movement.position);
      if (Cesium.defined(picked) && picked.id) {
        const entity = picked.id;
        const cartesian = this.viewer.scene.pickPosition(movement.position);
        callback({
          entity,
          position: cartesian,
          screenPosition: movement.position
        });
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  // 销毁地图
  /**
   * 销毁 Cesium Viewer 实例，释放资源
   */
  destroy() {
    this.viewer && this.viewer.destroy();
    this.viewer = null;
  }

  // 静态常量和工具类统一暴露
  static Color = Cesium.Color;
  static Cartesian3 = Cesium.Cartesian3;
  static Math = Cesium.Math;
  static ScreenSpaceEventType = Cesium.ScreenSpaceEventType;
  static Cartographic = Cesium.Cartographic;
  static HeadingPitchRange = Cesium.HeadingPitchRange;
  static UrlTemplateImageryProvider = Cesium.UrlTemplateImageryProvider;
  static WebMapTileServiceImageryProvider = Cesium.WebMapTileServiceImageryProvider;
  static Cesium3DTileset = Cesium.Cesium3DTileset;

  /**
   * 计算两点间空间距离（米）
   * @param {[number, number]} p1 - [lon, lat] 点1
   * @param {[number, number]} p2 - [lon, lat] 点2
   * @returns {number} - 距离（米）
   */
  static calcDistance(p1, p2) {
    const c1 = CesiumMap.Cartesian3.fromDegrees(...p1);
    const c2 = CesiumMap.Cartesian3.fromDegrees(...p2);
    return CesiumMap.Cartesian3.distance(c1, c2);
  }

  /**
   * 计算多点折线总长（米）
   * @param {Array<[number, number]>} positions - 经纬度数组
   * @returns {number} - 总长度（米）
   */
  static calcPolylineLength(positions) {
    let total = 0;
    for (let i = 1; i < positions.length; i++) {
      total += CesiumMap.calcDistance(positions[i - 1], positions[i]);
    }
    return total;
  }

  /**
   * 计算多边形面积（平方米，WGS84椭球面投影近似）
   * @param {Array<[number, number]>} positions - 经纬度数组
   * @returns {number} - 面积（平方米）
   */
  static calcPolygonArea(positions) {
    if (positions.length < 3) return 0;
    const radiansPerDegree = Math.PI / 180.0;
    const ellipsoid = Cesium.Ellipsoid.WGS84;
    let area = 0;
    for (let i = 0; i < positions.length; i++) {
      const p1 = positions[i];
      const p2 = positions[(i + 1) % positions.length];
      area += (p2[0] - p1[0]) * radiansPerDegree *
              (2 + Math.sin(p1[1] * radiansPerDegree) + Math.sin(p2[1] * radiansPerDegree));
    }
    area = area * ellipsoid.maximumRadius * ellipsoid.maximumRadius / 2.0;
    return Math.abs(area);
  }

  /**
   * 生成圆弧上的点（用于画弧形）
   * @param {[number, number]} center - 圆心 [lon, lat]
   * @param {number} radius - 半径（米）
   * @param {number} startAngle - 起始角度（度）
   * @param {number} endAngle - 终止角度（度）
   * @param {number} count - 插值点数量，越大越平滑
   * @returns {Array<[number, number]>} - 弧形上的经纬度点数组
   */
  static generateArcPoints(center, radius, startAngle, endAngle, count = 64) {
    const points = [];
    const toRad = Math.PI / 180;
    const [lon, lat] = center;
    for (let i = 0; i <= count; i++) {
      const angle = startAngle + (endAngle - startAngle) * (i / count);
      const dx = radius * Math.cos(angle * toRad);
      const dy = radius * Math.sin(angle * toRad);
      const dLon = dx / (111319.5 * Math.cos(lat * toRad));
      const dLat = dy / 111319.5;
      points.push([lon + dLon, lat + dLat]);
    }
    return points;
  }

  /**
   * 添加3D Tiles图层
   * @param {string} url - 3D Tiles URL
   * @param {object} options - 配置选项
   * @returns {Cesium3DTileset}
   */
  add3DTileset(url, options = {}) {
    return new Promise((resolve, reject) => {
      try {
        const tileset = new Cesium.Cesium3DTileset({
          url,
          maximumScreenSpaceError: 16,
          maximumMemoryUsage: 512,
          skipLevelOfDetail: true,
          baseScreenSpaceError: 1024,
          skipScreenSpaceErrorFactor: 16,
          ...options
        });
        
        // 等待tileset加载完成
        tileset.readyPromise.then(() => {
          this.viewer.scene.primitives.add(tileset);
          resolve(tileset);
        }).catch((error) => {
          console.error('3D Tiles加载失败:', error);
          reject(error);
        });
      } catch (error) {
        console.error('创建3D Tiles失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 移除3D Tiles图层
   * @param {Cesium3DTileset} tileset - 3D Tiles对象
   */
  remove3DTileset(tileset) {
    if (tileset && this.viewer.scene.primitives.contains(tileset)) {
      this.viewer.scene.primitives.remove(tileset);
    }
  }

  /**
   * 设置3D Tiles样式
   * @param {Cesium3DTileset} tileset - 3D Tiles对象
   * @param {object} style - 样式对象
   */
  set3DTilesStyle(tileset, style) {
    if (tileset && !tileset._isMock) {
      try {
        // 检查是否有 Cesium3DTileStyle 构造函数
        if (Cesium.Cesium3DTileStyle) {
          tileset.style = new Cesium.Cesium3DTileStyle(style);
        } else {
          console.warn('Cesium3DTileStyle 不可用，跳过样式设置');
        }
      } catch (error) {
        console.error('设置3D Tiles样式失败:', error);
      }
    }
  }

  /**
   * 检查Cesium版本兼容性
   * @returns {object} 兼容性信息
   */
  checkCompatibility() {
    const compatibility = {
      version: Cesium.VERSION || 'unknown',
      hasCreateWorldTerrain: !!Cesium.createWorldTerrain,
      hasCesium3DTileStyle: !!Cesium.Cesium3DTileStyle,
      hasCesiumTerrainProvider: !!Cesium.CesiumTerrainProvider,
      hasIonResource: !!Cesium.IonResource,
      supported: true,
      warnings: []
    };
    
    if (!compatibility.hasCreateWorldTerrain) {
      compatibility.warnings.push('createWorldTerrain 方法不可用，将使用替代方案');
    }
    
    if (!compatibility.hasCesium3DTileStyle) {
      compatibility.warnings.push('Cesium3DTileStyle 不可用，样式设置功能受限');
    }
    
    if (!compatibility.hasCesiumTerrainProvider) {
      compatibility.warnings.push('CesiumTerrainProvider 不可用，地形功能受限');
      compatibility.supported = false;
    }
    
    console.log('Cesium 兼容性检查:', compatibility);
    return compatibility;
  }

  /**
   * 异步添加地形数据
   * @param {string} url - 地形数据URL
   * @returns {Promise<Terrain>}
   */
  async addTerrainAsync(url) {
    return new Promise((resolve, reject) => {
      try {
        // 检查兼容性
        const compatibility = this.checkCompatibility();
        
        // 使用更兼容的方法创建地形
        let terrain;
        
        // 检查是否有 createWorldTerrain 方法
        if (Cesium.createWorldTerrain) {
          terrain = Cesium.createWorldTerrain({
            requestWaterMask: true,
            requestVertexNormals: true
          });
        } else if (Cesium.CesiumTerrainProvider && Cesium.IonResource) {
          // 使用 Cesium World Terrain
          terrain = new Cesium.CesiumTerrainProvider({
            url: Cesium.IonResource.fromAssetId(1),
            requestWaterMask: true,
            requestVertexNormals: true
          });
        } else {
          console.warn('地形功能不可用，请检查Cesium版本');
          resolve(null);
          return;
        }
        
        // 等待地形准备就绪
        if (terrain.readyPromise) {
          terrain.readyPromise.then(() => {
            // 设置地形提供者
            this.viewer.terrainProvider = terrain;
            
            // 确保地图继续渲染
            this.viewer.scene.requestRender();
            
            resolve(terrain);
          }).catch((error) => {
            console.error('地形加载失败:', error);
            reject(error);
          });
        } else {
          // 如果没有readyPromise，直接设置
          this.viewer.terrainProvider = terrain;
          this.viewer.scene.requestRender();
          resolve(terrain);
        }
      } catch (error) {
        console.error('创建地形失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 添加地形数据
   * @param {string} url - 地形数据URL
   * @returns {Terrain}
   */
  addTerrain(url) {
    try {
      // 检查兼容性
      const compatibility = this.checkCompatibility();
      
      // 使用更兼容的方法创建地形
      let terrain;
      
      // 检查是否有 createWorldTerrain 方法
      if (Cesium.createWorldTerrain) {
        terrain = Cesium.createWorldTerrain({
          requestWaterMask: true,
          requestVertexNormals: true
        });
      } else if (Cesium.CesiumTerrainProvider && Cesium.IonResource) {
        // 使用 Cesium World Terrain
        terrain = new Cesium.CesiumTerrainProvider({
          url: Cesium.IonResource.fromAssetId(1),
          requestWaterMask: true,
          requestVertexNormals: true
        });
      } else {
        console.warn('地形功能不可用，请检查Cesium版本');
        return null;
      }
      
      // 设置地形提供者
      this.viewer.terrainProvider = terrain;
      
      // 确保地图继续渲染
      this.viewer.scene.requestRender();
      
      return terrain;
    } catch (error) {
      console.error('添加地形失败:', error);
      // 如果添加失败，返回null
      return null;
    }
  }

  /**
   * 添加热力图
   * @param {Array} data - 热力图数据 [{lon, lat, value}, ...]
   * @param {object} options - 配置选项
   * @returns {Entity}
   */
  addHeatmap(data, options = {}) {
    // 创建多个热力图点，模拟热力图效果
    const entities = [];
    
    data.forEach(item => {
      const value = item.value;
      const intensity = Math.min(value / 100, 1); // 归一化到0-1
      
      // 根据数值大小设置不同的颜色和大小
      let color, size;
      if (value >= 80) {
        color = Cesium.Color.RED.withAlpha(0.8);
        size = 25;
      } else if (value >= 60) {
        color = Cesium.Color.ORANGE.withAlpha(0.7);
        size = 20;
      } else if (value >= 40) {
        color = Cesium.Color.YELLOW.withAlpha(0.6);
        size = 15;
      } else {
        color = Cesium.Color.GREEN.withAlpha(0.5);
        size = 10;
      }
      
      const entity = this.viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat),
        point: {
          pixelSize: size,
          color: color,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 1
        },
        label: {
          text: `热度: ${value}`,
          font: '12pt sans-serif',
          fillColor: Cesium.Color.WHITE,
          backgroundColor: color,
          outlineColor: Cesium.Color.BLACK,
          outlineWidth: 1,
          pixelOffset: new Cesium.Cartesian2(0, -size - 5),
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        },
        description: `热力图数据点\n位置: ${item.lon.toFixed(4)}, ${item.lat.toFixed(4)}\n热度值: ${value}`
      });
      
      entities.push(entity);
    });
    
    // 返回第一个实体作为主要引用，但实际包含所有实体
    const mainEntity = entities[0];
    mainEntity._heatmapEntities = entities;
    return mainEntity;
  }

  /**
   * 添加聚类点
   * @param {Array} points - 点数据数组
   * @param {object} options - 配置选项
   */
  addClusteredPoints(points, options = {}) {
    const entities = points.map(point => 
      this.addEntity({
        position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
        point: {
          pixelSize: options.pixelSize || 8,
          color: options.color || Cesium.Color.YELLOW,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        },
        name: point.name || '',
        description: point.description || ''
      })
    );
    return entities;
  }

  /**
   * 添加动态效果（闪烁）
   * @param {Entity} entity - 实体对象
   * @param {object} options - 配置选项
   */
  addBlinkingEffect(entity, options = {}) {
    const duration = options.duration || 1000;
    const color1 = options.color1 || Cesium.Color.RED;
    const color2 = options.color2 || Cesium.Color.TRANSPARENT;
    
    if (entity.point) {
      let isVisible = true;
      const interval = setInterval(() => {
        isVisible = !isVisible;
        entity.point.color = isVisible ? color1 : color2;
      }, duration / 2);
      
      // 存储interval以便后续清除
      entity._blinkingInterval = interval;
    }
  }

  /**
   * 移除闪烁效果
   * @param {Entity} entity - 实体对象
   */
  removeBlinkingEffect(entity) {
    if (entity._blinkingInterval) {
      clearInterval(entity._blinkingInterval);
      delete entity._blinkingInterval;
    }
  }

  /**
   * 添加轨迹动画
   * @param {Array} positions - 轨迹点数组 [{lon, lat, time}, ...]
   * @param {object} options - 配置选项
   * @returns {Entity}
   */
  addTrajectoryAnimation(positions, options = {}) {
    const timeStepInSeconds = options.timeStep || 30;
    const totalSeconds = timeStepInSeconds * (positions.length - 1);
    const start = Cesium.JulianDate.fromDate(new Date());
    const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate());
    
    this.viewer.clock.startTime = start.clone();
    this.viewer.clock.stopTime = stop.clone();
    this.viewer.clock.currentTime = start.clone();
    this.viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
    this.viewer.clock.multiplier = 1;
    this.viewer.clock.shouldAnimate = true;
    
    if (this.viewer.timeline) {
      this.viewer.timeline.zoomTo(start, stop);
    }
    
    const positionProperty = new Cesium.SampledPositionProperty();
    positions.forEach((pos, index) => {
      const time = Cesium.JulianDate.addSeconds(start, index * timeStepInSeconds, new Cesium.JulianDate());
      const position = Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat, pos.height || 0);
      positionProperty.addSample(time, position);
    });
    
    return this.viewer.entities.add({
      availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
        start: start,
        stop: stop
      })]),
      position: positionProperty,
      point: {
        pixelSize: options.pixelSize || 10,
        color: options.color || Cesium.Color.YELLOW,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2
      },
      path: {
        show: true,
        leadTime: 0,
        trailTime: timeStepInSeconds * 2,
        width: 3,
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.2,
          color: Cesium.Color.YELLOW
        }),
        resolution: 1
      }
    });
  }

  /**
   * 截图功能
   * @param {object} options - 截图选项
   * @returns {Promise<string>}
   */
  async takeScreenshot(options = {}) {
    const canvas = this.viewer.scene.canvas;
    const dataURL = canvas.toDataURL('image/png');
    return dataURL;
  }

  /**
   * 设置全屏模式
   * @param {boolean} fullscreen - 是否全屏
   */
  setFullscreen(fullscreen) {
    if (fullscreen) {
      this.viewer.scene.screenSpaceCameraController.enableCollisionDetection = false;
      this.viewer.scene.screenSpaceCameraController.enableZoom = true;
      this.viewer.scene.screenSpaceCameraController.enableRotate = true;
      this.viewer.scene.screenSpaceCameraController.enableTranslate = true;
    }
  }

  /**
   * 添加标注
   * @param {object} param0 - { lon, lat, text, font, color, backgroundColor, outlineColor, outlineWidth }
   * @returns {Entity}
   */
  addLabel({ lon, lat, text, font = '14pt sans-serif', color = Cesium.Color.WHITE, backgroundColor = Cesium.Color.BLACK.withAlpha(0.7), outlineColor = Cesium.Color.BLACK, outlineWidth = 2 }) {
    return this.viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(lon, lat),
      label: {
        text,
        font,
        fillColor: color,
        backgroundColor,
        outlineColor,
        outlineWidth,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(0, -10),
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
      }
    });
  }

  /**
   * 测量高度
   * @param {Array} positions - 测量点数组
   * @returns {number} 高度差
   */
  measureHeight(positions) {
    if (positions.length < 2) return 0;
    
    const p1 = Cesium.Cartographic.fromCartesian(
      Cesium.Cartesian3.fromDegrees(positions[0][0], positions[0][1])
    );
    const p2 = Cesium.Cartographic.fromCartesian(
      Cesium.Cartesian3.fromDegrees(positions[1][0], positions[1][1])
    );
    
    return Math.abs(p2.height - p1.height);
  }

  /**
   * 测量角度
   * @param {Array} positions - 三个点数组
   * @returns {number} 角度（弧度）
   */
  measureAngle(positions) {
    if (positions.length < 3) return 0;
    
    const p1 = Cesium.Cartesian3.fromDegrees(positions[0][0], positions[0][1]);
    const p2 = Cesium.Cartesian3.fromDegrees(positions[1][0], positions[1][1]);
    const p3 = Cesium.Cartesian3.fromDegrees(positions[2][0], positions[2][1]);
    
    const v1 = Cesium.Cartesian3.subtract(p1, p2, new Cesium.Cartesian3());
    const v2 = Cesium.Cartesian3.subtract(p3, p2, new Cesium.Cartesian3());
    
    Cesium.Cartesian3.normalize(v1, v1);
    Cesium.Cartesian3.normalize(v2, v2);
    
    return Math.acos(Cesium.Cartesian3.dot(v1, v2));
  }

  /**
   * 重置地图显示
   */
  resetMap() {
    try {
      // 清除地形提供者
      this.viewer.terrainProvider = undefined;
      
      // 重新设置基础图层
      if (this.viewer.imageryLayers.length === 0) {
        this.viewer.imageryLayers.addImageryProvider(
          new Cesium.OpenStreetMapImageryProvider({
            url: 'https://a.tile.openstreetmap.org/'
          })
        );
      }
      
      // 重置相机位置
      this.viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(116.3974, 39.9087, 1000),
        orientation: {
          heading: 0.0,
          pitch: -Math.PI / 2,
          roll: 0.0
        }
      });
      
      // 强制重新渲染
      this.viewer.scene.requestRender();
      
      console.log('地图已重置');
    } catch (error) {
      console.error('重置地图失败:', error);
    }
  }
} 